﻿// ....................................................................................................................
//	Author: Copyright (C) 2012 Ing. Marek Hubal
//	Email: hubal@acasoftware.org
// ....................................................................................................................

using System;

namespace core
{
    /// <summary>Trieda IApp</summary>
	public class IApp : IDisposable
	{
        public const int CHECK_UPDATE_INTERVAL = 1000 * 60 * 60 * 8;

        public static IApp App; // Jedina instancia objektu
        public static IConfig Config; // Jedina instancia objektu
        public static ISettings Settings; // Jedina instacia objektu
        public static ICmd CMD; // Jedina instancia objektu
        public static IAppForm AppForm; // Jedina instancia objektu
        public static IVisualTheme CurrentVisualTheme; // Aktualna vizualna tema
        public static IGlobalData GlobalData; // Globalne data

        public string DataPath; // Datovy priecinok aplikacie
        public string AppTitle; // Titulka aplikacie
        public System.Windows.Forms.ImageList AppSmallImageList; // Zoznam maly ikoniec aplikacie
        public bool EnabledEscMonitor; // Priznak povoleneho monitorovania esc

        // Synchronizacne premenne
        public IThrSafeVariable CurrentExtractIconObjectName; // Aktualny objekt, z ktoreho sa extrahuje ikona

        protected int FEscMonitorCounter; // Pocitadlo monitoringu klavesy ESC
        protected ulong FInstalledInstanceID; // Ulozene ID instalacie instancie

        protected System.Windows.Forms.Timer FUpdateTimer; // Casovac pre automaticke kontrolovanie novych verzii
        protected int FUpdateState; // Aktualny stav aktualizacie
        protected string FLastReadedUpdateData; // Posledne nacitane data z webu o aktualizacii
        protected string FNewAvailableVersion; // Najnovsia dostupna verzia
        protected string FNewAvailableVersion_Url; // URL na stiahnutie najnovsej verzie
        protected string FNewAvailableVersionHashTag; // Hash tag najnovsej dostupnej verzie

        /// <summary>Event: EnterThreadModal</summary>
        /// <param name="pSender">zdroj</param>
        /// <param name="e">parameter</param>
        protected void Event_EnterThreadModal(object pSender, EventArgs e)
        {
            IApp.CMD.IsShortcutsEnabled = false;
        }
        /// <summary>Event: LeaveThreadModal</summary>
        /// <param name="pSender">zdroj</param>
        /// <param name="e">parameter</param>
        protected void Event_LeaveThreadModal(object pSender, EventArgs e)
        {
            IApp.CMD.IsShortcutsEnabled = true;
        }
        /// <summary>Nacitanie zdrojov</summary>
        protected void LoadResources()
        {
            AppSmallImageList = new System.Windows.Forms.ImageList(); // Vytvorim objekt
            AppSmallImageList.ColorDepth = System.Windows.Forms.ColorDepth.Depth32Bit;
            AppSmallImageList.ImageSize = new System.Drawing.Size(16, 16);

            AppSmallImageList.Images.Add(core.Properties.Resources.folder_16x16); // Pridam ikonky
            AppSmallImageList.Images.Add(core.Properties.Resources.file_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.cdrom_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.hdd_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.floppy_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.network_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.removable_16x16);
            AppSmallImageList.Images.Add(core.Properties.Resources.computers_16x16);
        }

        /// <summary>Callback pre SHBrowseForFolder</summary>
        /// <param name="hwnd">handle</param>
        /// <param name="uMsg"></param>
        /// <param name="lParam"></param>
        /// <param name="lpData"></param>
        /// <returns></returns>
        protected static int BFFCALLBACK(IntPtr hwnd, uint uMsg, IntPtr lParam, IntPtr lpData)
        {
            if (uMsg == IWin32.BFFM_INITIALIZED)
            { // Inicializacia
                System.Text.StringBuilder B = new System.Text.StringBuilder(System.Runtime.InteropServices.Marshal.PtrToStringBSTR(lpData));
                IWin32.User32.SendMessage(hwnd, (int)IWin32.BFFM_SETSELECTIONA, 1, B); // Nastavim startovaciu cestu
            }
            return 0;
        }

        /// <summary>Property: InstalledInstanceID</summary>
        public ulong InstalledInstanceID
        {
            get
            {
                if (FInstalledInstanceID == 0) FInstalledInstanceID = ICore.GetProcessorID() ^ ICore.GetMBID();
                return FInstalledInstanceID;
            }
        }

        /// <summary>Konstruktor</summary>
        public IApp()
        {
            IApp.App = this; // Ulozim instanciu
            FEscMonitorCounter = 0;
            FInstalledInstanceID = 0;
            EnabledEscMonitor = true;
            IWin32.Kernel32.SetErrorMode(IWin32.SEM_FAILCRITICALERRORS);

            CurrentExtractIconObjectName = new IThrSafeVariable();

            AppTitle = string.Format(lang.APP_TITLE, totalem.CURRENT_VERSION); // Titulka aplikacie
            DataPath = IFileSystem.AppendToPath(IFileSystem.GetSpecialPath(IFileSystem.SPECIAL_PATH_ID_USER_DATA), "totalem"); // Vytvorim datovu cestu
            IFileSystem.CreateFullDirectory(DataPath); // Vytvorim priecinok

            Config = new IConfig(); // Vytvorim a nacitam konfiguraciu
            Config.LoadConfiguration(IFileSystem.AppendToPath(DataPath, "totalem.cfg"));
            CorrectPreviousConfigurations(); // Volam korekcie konfiguracie

            Settings = new ISettings(); // Vytvorim a nacitam nastavenie
            Settings.Load();
            CMD = new ICmd(); // Vytvorim a nacitam klav. skratky
            CMD.Load();
            GlobalData = new IGlobalData(); // Globalne data
            GlobalData.Load();

            CurrentVisualTheme = new IVisualTheme(); // Vytvorim temu
            CurrentVisualTheme.LoadTheme(0);

            System.Windows.Forms.Application.AddMessageFilter(new ICmdMessageFilter()); // Zaradim message filter
            System.Windows.Forms.Application.EnterThreadModal += Event_EnterThreadModal;
            System.Windows.Forms.Application.LeaveThreadModal += Event_LeaveThreadModal;

            LoadResources(); // Nacitam zdroje

            FUpdateState = 0;
            FNewAvailableVersion = "";
            FNewAvailableVersion_Url = "";
            FNewAvailableVersionHashTag = "";
            FUpdateTimer = new System.Windows.Forms.Timer(); FUpdateTimer.Interval = 2000;
            FUpdateTimer.Tick += Event_TimerTick_Update; FUpdateTimer.Enabled = true;
        }
        /// <summary>Dispose metoda</summary>
        public void Dispose()
        {
            if (IApp.App == null) return; // Uz je zrusene?

            GlobalData.Save(); // Ulozim globalne data
            GlobalData = (IGlobalData)ICore.DisposeObject(GlobalData);
            CMD.Save(); // Ulozim a zrusim klav. skratky
            CMD = (ICmd)ICore.DisposeObject(CMD);
            Settings.Save(); // Ulozim a zrusim nastavenie
            Settings = (ISettings)ICore.DisposeObject(Settings);
            // Ulozim a zrusim konfiguraciu
            Config.SaveConfiguration(IFileSystem.AppendToPath(DataPath, "totalem.cfg"));
            Config = (IConfig)ICore.DisposeObject(Config);
            AppSmallImageList = (System.Windows.Forms.ImageList)ICore.DisposeObject(AppSmallImageList);
            CurrentVisualTheme = (IVisualTheme)ICore.DisposeObject(CurrentVisualTheme);
        }

        /// <summary>Oprava konfiguracii z predchadzajuich verzii</summary>
        public void CorrectPreviousConfigurations()
        {
            if (Config.Exists("CLOUD_STORAGES")) // Existuje "CLOUD_STORAGES"?
            {
                string Data = Config.GetParam("CLOUD_STORAGES", ""); // Ziskam hodnotu
                IFileSystem.SaveStringToTextFile(IFileSystem.AppendToPath(DataPath, "totalem.cloud_storages.cfg"), Data, true);
                Config.Delete("CLOUD_STORAGES");
            }
        }
        /// <summary>Ulozenie konfiguracie - cloud storages</summary>
        /// <param name="pData"></param>
        public void SaveOtherConfig_CloudStorages(string pData)
        {
            IFileSystem.SaveStringToTextFile(IFileSystem.AppendToPath(DataPath, "totalem.cloud_storages.cfg"), pData, true);
        }
        /// <summary>Nacitanie konfiguracie - cloud storages</summary>
        /// <returns>obsah</returns>
        public string LoadOtherConfig_CloudStorages()
        {
            string Result = "";
            return IFileSystem.LoadStringFromTextFile(IFileSystem.AppendToPath(DataPath, "totalem.cloud_storages.cfg"), out Result) == 0 ? Result : "";
        }

        /// <summary>Ukoncenie aplikacie</summary>
        /// <param name="pExitCode">exit kod</param>
        public void Exit(int pExitCode)
        {
            IWin32.User32.PostQuitMessage(pExitCode); // Poslem ukoncenie aplikacie
        }
        /// <summary>Aktualizacia objektu po zmene nastavenia</summary>
        public void UpdateAfterChangeSettings()
        {
            IApp.AppForm.UpdateAfterChangeSettings();
        }
        /// <summary>Zaciatok monitorovania klavesy ESC</summary>
        public void StartMonitorEscape()
        {
            FEscMonitorCounter++;
        }
        /// <summary>Koniec monitorovania klavesy ESC</summary>
        public void StopMonitorEscape()
        {
            if (FEscMonitorCounter > 0) FEscMonitorCounter--;
        }
        /// <summary>Property: IsEscapeMonitored</summary>
        public bool IsEscapeMonitored
        {
            get
            {
                return FEscMonitorCounter > 0;
            }
        }
        /// <summary>Property: IsEscPressed</summary>
        public bool IsEscPressed
        {
            get
            {
                if (!EnabledEscMonitor)
                {
                    if ((IWin32.User32.GetAsyncKeyState(IWin32.VK_ESCAPE) & 0x8000) == 0) EnabledEscMonitor = true;
                    return false;
                }
                if (FEscMonitorCounter == 0) return false;
                return (IWin32.User32.GetAsyncKeyState(IWin32.VK_ESCAPE) & 0x8000) != 0;
            }
        }
        /// <summary>Property: IsCtrlPressed</summary>
        public bool IsCtrlPressed
        {
            get
            {
                return (IWin32.User32.GetAsyncKeyState(IWin32.VK_CONTROL) & 0x8000) != 0;
            }
        }
        /// <summary>Property: IsShiftPressed</summary>
        public bool IsShiftPressed
        {
            get
            {
                return (IWin32.User32.GetAsyncKeyState(IWin32.VK_SHIFT) & 0x8000) != 0;
            }
        }
        /// <summary>Property: IsCtrlPressed</summary>
        public bool IsAltPressed
        {
            get
            {
                return (IWin32.User32.GetAsyncKeyState(IWin32.VK_MENU) & 0x8000) != 0;
            }
        }
        /// <summary>Property: WaitCursor</summary>
        public bool WaitCursor
        {
            set
            {
                System.Windows.Forms.Cursor.Current = value ? System.Windows.Forms.Cursors.WaitCursor : System.Windows.Forms.Cursors.Arrow;
                System.Windows.Forms.Application.UseWaitCursor = value;
            }
            get
            {
                return System.Windows.Forms.Application.UseWaitCursor;
            }
        }
        /// <summary>Aktualizacia objektu po zmene vizualnej temy</summary>
        public void UpdateAfterChangeVisualTheme()
        {
            IApp.AppForm.UpdateAfterChangeVisualTheme();
        }

        /// <summary>Event: Tick pre update casovac</summary>
        /// <param name="pSender">zdroj</param>
        /// <param name="e">parameter</param>
        protected void Event_TimerTick_Update(object pSender, EventArgs e)
        {
            switch (FUpdateState)
            {
                case 0: // Nic sa nerobi
                    {
                        FUpdateState = 1; // Nacitavaju sa data
                        System.Threading.Thread Thr = new System.Threading.Thread(delegate()
                        {
                            FLastReadedUpdateData = ICore.GetWebPage(string.Format("http://www.acasoftware.org/services/totalem_check_update.aspx?UPDATE_ID={0}&IN_ID={1}", totalem.CURRENT_VERSION_HASH_TAG, IApp.App.InstalledInstanceID));
                            if (string.IsNullOrEmpty(FLastReadedUpdateData)) FUpdateState = 0;
                            else FUpdateState = 2;
                        });

                        Thr.SetApartmentState(System.Threading.ApartmentState.MTA);
                        Thr.IsBackground = true;
                        Thr.Priority = System.Threading.ThreadPriority.Lowest;

                        FUpdateTimer.Interval = 1000; // Zmenim na sekundovy
                        Thr.Start();
                    } break;
                case 2: // Dekodujem nacitane vysledky
                    {
                        FUpdateState = 3; // Cakam na dekodovanie
                        try
                        {
                            string[] Lines = FLastReadedUpdateData.Split(new char[] { '\b' }, StringSplitOptions.None);
                            if (Lines.Length == 3)
                            {
                                if ((Lines[0] != totalem.CURRENT_VERSION_HASH_TAG) && (Lines[0] != FNewAvailableVersionHashTag)) // Je nova verzia?
                                {
                                    FNewAvailableVersionHashTag = Lines[0];
                                    FNewAvailableVersion = Lines[1];
                                    FNewAvailableVersion_Url = Lines[2];
                                    FUpdateState = 4; // Zobrazujem vysledok
                                    return;
                                }
                            }
                            FUpdateTimer.Interval = CHECK_UPDATE_INTERVAL;
                            FUpdateState = 0; // Chyba
                            return;
                        }
                        catch
                        {
                            FUpdateTimer.Interval = CHECK_UPDATE_INTERVAL;
                            FUpdateState = 0; // Chyba
                            return;
                        }
                    }
                case 4:
                    {
                        FUpdateState = 5;
                        if (IApp.Settings.App_AutoShowUpdateAvailable) ShowUpdateInformation(false); // Zobrazim info o aktualizacii
                        FUpdateTimer.Interval = CHECK_UPDATE_INTERVAL;
                        FUpdateState = 0;
                    } break;
            }
        }
        
        /// <summary>Process all event for window</summary>
        /// <param name="pHandle">handle of window</param>
        public static void DoEvents(IntPtr pHandle)
        {
            IWin32.MSG msg = new IWin32.MSG(); // Allocate structure
            while (true)
            {
                if (!IWin32.User32.PeekMessage(ref msg, pHandle.ToInt32(), 0, 0, 0)) return; // Is some message?
                IWin32.User32.GetMessage(ref msg, pHandle.ToInt32(), 0, 0); // Process message
                IWin32.User32.TranslateMessage(ref msg);
                IWin32.User32.DispatchMessage(ref msg);
            }
        }
        /// <summary>Poslanie spravy o stlaceni klavesy controls</summary>
        /// <param name="pControl"></param>
        /// <param name="pKey"></param>
        public static void SendKeyboardMessage(System.Windows.Forms.Control pControl, System.Windows.Forms.Keys pKey)
        {
            IWin32.User32.SendMessage(pControl.Handle, IWin32.WM_KEYDOWN, (int)pKey, 0);
        }

        /// <summary>Zobrazenie otazky</summary>
        /// <param name="pMsg">otazka</param>
        /// <returns>true / false</returns>
        public static bool ShowQuestion(string pMsg)
        {
            return System.Windows.Forms.MessageBox.Show(pMsg, IApp.App.AppTitle, System.Windows.Forms.MessageBoxButtons.OKCancel, System.Windows.Forms.MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.OK;
        }
        /// <summary>Zobrazenie informacie</summary>
        /// <param name="pMsg">sprava</param>
        public static void ShowInfo(string pMsg)
        {
            System.Windows.Forms.MessageBox.Show(pMsg, IApp.App.AppTitle, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
        }
        /// <summary>Zobrazenie chyby</summary>
        /// <param name="pMsg">sprava</param>
        public static void ShowError(string pMsg)
        {
            System.Windows.Forms.MessageBox.Show(pMsg, IApp.App.AppTitle, System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error);
        }

        /// <summary>Otvorenie URL v prednastavenom prehliadaci</summary>
        /// <param name="pURL">URL adresa</param>
        /// <returns>true / false</returns>
        public static bool OpenURL(string pURL)
        {
            string S = string.Format("url.dll,FileProtocolHandler {0}", pURL);
            return IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", "rundll32.exe", S, null, IWin32.SW_MAXIMIZE).ToInt32() > 0;
        }
        /// <summary>Run file / open with associated application</summary>
        /// <param name="pName"></param>
        public static void RunFile(string pName, string pWorkingDirectory = "")
        {
            if (IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", pName, "", pWorkingDirectory, IWin32.SW_NORMAL).ToInt32() == IWin32.SE_ERR_NOASSOC)
            {
                string S = "shell32.dll,OpenAs_RunDLL "; S += pName;
                IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", "rundll32.exe", S, pWorkingDirectory, IWin32.SW_NORMAL);
            }
        }
        /// <summary>Otvorenie command promptu</summary>
        /// <param name="pPath">cesta</param>
        public static void OpenCommand(string pPath)
        {
            string Path = System.Environment.GetEnvironmentVariable("COMSPEC");
            if (string.IsNullOrEmpty(Path)) return; // Nenasiel som cestu ku cmd.exe

            IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", Path, "", pPath, IWin32.SW_NORMAL); // Spustim
        }
        /// <summary>Spustenie externeho editora</summary>
        /// <param name="pFileName">subor na otvorenie</param>
        public static void RunExternalEditor(string pFileName, string pWorkingDirectory = "")
        {
            string EditorName = IApp.Settings.FileExplorer_ExternalEditor;
            if (EditorName == "")
            {
                EditorName = IFileSystem.AppendToPath(IFileSystem.GetSpecialPath(IFileSystem.SPECIAL_PATH_ID_WINDOWS), "notepad.exe");
            }
            IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", EditorName, pFileName, pWorkingDirectory, IWin32.SW_NORMAL);
        }
        /// <summary>Spustenie externeho prehliadaca</summary>
        /// <param name="pFileName">subor na otvorenie</param>
        public static void RunExternalViewer(string pFileName, string pWorkingDirectory = "")
        {
            string EditorName = IApp.Settings.FileExplorer_ExternalViewer;
            if (EditorName == "")
            {
                EditorName = IFileSystem.AppendToPath(IFileSystem.GetSpecialPath(IFileSystem.SPECIAL_PATH_ID_WINDOWS), "notepad.exe");
            }
            IWin32.Shell32.ShellExecute(IntPtr.Zero, "open", EditorName, pFileName, pWorkingDirectory, IWin32.SW_NORMAL);
        }

        /// <summary>Zobrazenie editora - vyber moznosti zo zoznamu</summary>
        /// <param name="pCaption1">nadpis okna</param>
        /// <param name="pCaption2">podnadpis</param>
        /// <param name="pChoiceNames">nazvy volieb</param>
        /// <param name="pChoiceNotes">popisy volieb</param>
        /// <param name="pChoice">prednastavena a vysledna volba</param>
        /// <param name="pChoiceSeparator">oddelovac volieb v nazvoch a popisoch</param>
        /// <returns>true / false</returns>
        public static bool ShowEditor_ChooseFromList(string pCaption1, string pCaption2, string pChoiceNames, string pChoiceNotes, ref int pChoice, char pChoiceSeparator = '\b')
        {
            using (IForm_ChooseFromList F = new IForm_ChooseFromList()) // Vytvorim okno
            {
                F.Choice = pChoice; F.Caption = pCaption2; F.Text = pCaption1; F.ChoiceNames = pChoiceNames; F.ChoiceNotes = pChoiceNotes; F.ChoiceSeparator = pChoiceSeparator;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK; // Zobrazim
                if (B) pChoice = F.Choice; // Ulozim vysledok
                return B;
            }
        }
        /// <summary>Zobrazenie editora - boolean</summary>
        /// <param name="pCaption1">nadpis okna</param>
        /// <param name="pCaption2">podnadpis</param>
        /// <param name="pChoiceNotes">popisy volieb</param>
        /// <param name="pChoice">prednastavena a vysledna volba</param>
        /// <param name="pChoiceSeparator">oddelovac volieb v nazvoch a popisoch</param>
        /// <returns>true / false</returns>
        public static bool ShowEditor_Boolean(string pCaption1, string pCaption2, string pChoiceNotes, ref bool pChoice, char pChoiceSeparator = '\b')
        {
            int Val = pChoice ? 0 : 1;
            bool B = ShowEditor_ChooseFromList(pCaption1, pCaption2, lang.APPFORM_TEXT_3, pChoiceNotes, ref Val, pChoiceSeparator); // Volam vyber
            if (B) pChoice = Val == 0;
            return B;
        }
        /// <summary>Zobrazenie editora pre vyber farby</summary>
        /// <param name="Font">prednastavena farba a vysledok</param>
        /// <returns>true / false</returns>
        public static bool ShowEditor_ChooseColor(ref System.Drawing.Color Color)
        {
            using (System.Windows.Forms.ColorDialog F = new System.Windows.Forms.ColorDialog()) // Vytvorim formular
            {
                F.Color = Color;
                F.AllowFullOpen = true;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK; // Zobrazim
                if (B) // Je potvrdeny vyber?
                {
                    Color = F.Color;
                }
                return B; // Vratim priznak potvrdenia
            }
        }
        /// <summary>Zobrazenie editora pre vyber pisma</summary>
        /// <param name="Font">prednastaveny font a vysledok</param>
        /// <returns>true / false</returns>
        public static bool ShowEditor_ChooseFont(ref System.Drawing.Font Font)
        {
            using (System.Windows.Forms.FontDialog F = new System.Windows.Forms.FontDialog()) // Vytvorim formular
            {
                F.FontMustExist = true; // Nastavim parametre
                F.Font = Font;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK; // Zobrazim
                if (B) // Je potvrdeny vyber?
                {
                    Font = (System.Drawing.Font)ICore.DisposeObject(Font);
                    Font = (System.Drawing.Font)F.Font.Clone(); // Skopirujem vysledok
                }
                return B; // Vratim priznak potvrdenia
            }
        }
        /// <summary>Vyber priecinku pouzitim okna</summary>
        /// <param name="pTitle">titulka</param>
        /// <param name="pPath">aktualna cesta</param>
        /// <returns>vybrana cesta alebo null</returns>
        public static string ShowEditor_ChooseDirectory(string pTitle, string pPath)
        {
            IntPtr buffer = System.Runtime.InteropServices.Marshal.AllocHGlobal(260); // Alokujem pamat
            System.Text.StringBuilder B = new System.Text.StringBuilder(260); // Vytvorim StringBuilder s alokovanou pamatou
            IntPtr pidl = IntPtr.Zero;

            IWin32.BROWSEINFO bi = new IWin32.BROWSEINFO(); // Alokujem a vyplnim struktoru
            bi.hwndOwner = System.Windows.Forms.Form.ActiveForm.Handle;
            bi.iImage = 0;
            bi.lParam = System.Runtime.InteropServices.Marshal.StringToBSTR(pPath);
            bi.lpfn = new IWin32.BFFCALLBACK(BFFCALLBACK);
            bi.lpszTitle = pTitle;
            bi.pidlRoot = IntPtr.Zero;
            bi.pszDisplayName = buffer;
            bi.ulFlags = (int)IWin32.BIF_NONEWFOLDERBUTTON;

            try
            {
                pidl = IWin32.Shell32.SHBrowseForFolder(ref bi); // Zavolam zobrazenie okna
                System.Runtime.InteropServices.Marshal.FreeHGlobal(buffer); // Uvolnim buffer
                if (IWin32.Shell32.SHGetPathFromIDList(pidl, B) == 0) return ""; // Ak sa mi nepodari ziskat cestu tak koncim
            }
            finally
            {
                System.Runtime.InteropServices.Marshal.FreeCoTaskMem(pidl); // Uvolnim objekt
                System.Runtime.InteropServices.Marshal.FreeBSTR(bi.lParam);
            }
            return B.ToString(); // Vratim cestu
        }
        /// <summary>Zobrazenie editora pre zadanie retazca</summary>
        /// <param name="pTitle">titulka okna</param>
        /// <param name="pCaption">nadpis</param>
        /// <param name="Value">prednastavena hodnota a vysledok</param>
        /// <param name="pMaxLength">max. dlzka retazca</param>
        /// <param name="pCanBeEmpty">priznak moznosti prazdneho vysledku</param>
        /// <param name="pAutoCompleteResourceName">nazov resource pre autocomplete</param>
        /// <param name="pAutoCompleteData">priame data pre autocomplete</param>
        /// <param name="pPasswordMode">priznak zadavania hesla</param>
        /// <returns>true / false</returns>
        public static bool ShowEditor_String(string pTitle, string pCaption, ref string Value, int pMaxLength = -1, bool pCanBeEmpty = true, string pAutoCompleteResourceName = null, string pAutoCompleteData = null, bool pPasswordMode = false)
        {
            using (IForm_EditString F = new IForm_EditString())
            {
                F.Text = pTitle; F.Caption = pCaption; F.MaxLength = pMaxLength; F.CanBeEmpty = pCanBeEmpty; F.Value = Value; F.PasswordMode = pPasswordMode; // Ulozim vstupne parametre
                F.AutoCompleteData = pAutoCompleteData; F.AutoCompleteResourceName = pAutoCompleteResourceName;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK;
                if (B) Value = F.Value;
                return B;
            }
        }
        /// <summary>Zobrazenie editora pre vyber nazvu suboru pre ulozenie</summary>
        /// <param name="pTitle">titulka okna</param>
        /// <param name="pFilter">filter suborov</param>
        /// <param name="pStartPath">pociatocna cesta</param>
        /// <param name="pDefaultFileName">prednastavene meno</param>
        /// <returns>vybrany nazov alebo null</returns>
        public static string ShowEditor_ChooseFileSave(string pTitle, string pFilter, string pStartPath = "", string pDefaultFileName = "")
        {
            string Result = null;
            using (System.Windows.Forms.SaveFileDialog F = new System.Windows.Forms.SaveFileDialog()) // Vytvorim formular
            {
                F.Title = pTitle;
                F.Filter = pFilter;
                F.InitialDirectory = pStartPath;
                if (!string.IsNullOrEmpty(pDefaultFileName))
                {
                    F.InitialDirectory = IFileSystem.ExtractPath(pDefaultFileName);
                    F.FileName = IFileSystem.ExtractName(pDefaultFileName);
                }
                F.CheckPathExists = true;
                F.OverwritePrompt = true;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK; // Zobrazim
                if (B) Result = F.FileName;
            }
            return Result;
        }
        /// <summary>Zobrazenie editora pre vyber nazvu suboru pre nacitanie</summary>
        /// <param name="pTitle">titulka okna</param>
        /// <param name="pFilter">filter suborov</param>
        /// <returns>vybrany nazov alebo null</returns>
        public static string ShowEditor_ChooseFileLoad(string pTitle, string pFilter)
        {
            string Result = null;
            using (System.Windows.Forms.OpenFileDialog F = new System.Windows.Forms.OpenFileDialog()) // Vytvorim formular
            {
                F.Title = pTitle;
                F.Filter = pFilter;
                F.CheckFileExists = true;
                bool B = F.ShowDialog() == System.Windows.Forms.DialogResult.OK; // Zobrazim
                if (B) Result = F.FileName;
            }
            return Result;
        }
        /// <summary>Zobrazenie interneho prehliadaca</summary>
        /// <param name="pFileName">nazov suboru</param>
        public static void ShowInternalViewer(string pFileName)
        {
            IFileExplorerForm_Viewer F = new IFileExplorerForm_Viewer();
            F.FilesToView.Add(pFileName);
            F.Show();
        }
        /// <summary>Zobrazenie interneho prehliadaca</summary>
        /// <param name="pFileName">nazov suboru</param>
        public static void ShowInternalViewer(System.Collections.Generic.List<string> pFileNames)
        {
            IFileExplorerForm_Viewer F = new IFileExplorerForm_Viewer();
            F.FilesToView.AddRange(pFileNames);
            F.Show();
        }

        /// <summary>Zobrazenie informacii o aktualizacii</summary>
        public void ShowUpdateInformation(bool pShowNoUpdate = false)
        {
            if (FNewAvailableVersionHashTag == "")
            {
                if (pShowNoUpdate) IApp.ShowInfo(string.Format(lang.APPFORM_TEXT_8_1, totalem.CURRENT_VERSION));
                return; // Ziadna aktualizacia
            }
            if (!IApp.ShowQuestion(string.Format(lang.APPFORM_TEXT_8, totalem.CURRENT_VERSION, FNewAvailableVersion))) return; // Zobrazim info o aktualizacii
            IApp.OpenURL(FNewAvailableVersion_Url); // Otvorim URL
        }
    }
}
